package core;

import java.io.File;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;

import dbms.DBGeneralFunctions;
import dbms.DBSelectingFunctions;
import filemanager.FileManager;
import filemanager.FileTransferServerSocket;
import graphic.MainFrame;
import graphic.ToolBar;
import graphic.dialogs.ServerConfigurationDialog;

public class Server {

	public static Server SERVER;
	
	HashMap<Integer, String> configs;
	HashMap<String, FileManager> programs;
	HashMap<String, LoggedUserThread> users;
		
	public Server()
	{
		this.programs = new HashMap<String, FileManager>();
		this.users = new HashMap<String, LoggedUserThread>();	
	}
	
	protected void init()
	{
		MainFrame.getInstance();
		
		if(!Configuration.isConfigured())
			new ServerConfigurationDialog();
		else
			ToolBar.getInstance().disableAllButtonsInsteadOf(ToolBar.ONLY_RUN);
	}
	
	public void startServer()
	{
		try {
			this.configs = DBGeneralFunctions.getServerConfigurationMap();
			
			File temp = new File(Server.getInstance().getConfigs().get(2) + "/" + Server.getInstance().getConfigs().get(5));
			if(!temp.exists()) temp.mkdir();
			
			ResultSet programs = DBSelectingFunctions.getPrograms();
			while(programs.next())
				this.programs.put(programs.getString("name"), new FileManager(programs.getString("name"), programs.getString("extenzion")));
			
			ConnectionListener.getInstance();
			FileTransferServerSocket.getInstance();
			MainFrame.getInstance().startServer();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public void stopServer() throws IOException
	{
		ConnectionListener.getInstance().close();
		FileTransferServerSocket.getInstance().close();
		ToolBar.getInstance().disableAllButtonsInsteadOf(ToolBar.ONLY_RUN);
		
		this.configs = null;
		this.programs = new HashMap<String, FileManager>();
		this.users = new HashMap<String, LoggedUserThread>();
		//FilesTabbedPanel.getInstance().refreshPanel();
	}
	
	public synchronized void sendFileLockInfoToAll(String programName, String fileName, String lock, String userId)
	{
		for (Iterator iterator = this.users.keySet().iterator(); iterator.hasNext();)
		{
			LoggedUserThread loggedUserThread = this.users.get((String) iterator.next());
			loggedUserThread.sendFileLockInfo(programName, fileName, lock, userId);			
		}
	}
	
	public void sendLoggedClientInfoToAll(String userId, boolean loggedIn)
	{
		for (Iterator iterator = this.users.keySet().iterator(); iterator.hasNext();)
		{
			LoggedUserThread loggedUserThread = this.users.get((String) iterator.next());
			loggedUserThread.sendLoggedClientInfo(userId, loggedIn);
		}
	}
	
	public void reInitAssociatedUsers(String programName)
	{
		ResultSet associatedUsers;
		try {
			associatedUsers = DBSelectingFunctions.getAssociatedUsers(programName);
			HashMap<String, LoggedUserThread> loggedUsers = Server.getInstance().getUsers();

			LoggedUserThread loggedUserThread;
			while(associatedUsers.next())
			{
				loggedUserThread = loggedUsers.get(associatedUsers.getString("utente"));
				if(loggedUserThread != null)
					loggedUserThread.initLoggedUser();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public HashMap<String, FileManager> getPrograms() { return programs; }
	
	public static Server getInstance()
	{
		if(SERVER == null) SERVER = new Server();
		return SERVER;
	}
	
	public HashMap<String, LoggedUserThread> getUsers() {
		return users;
	}

	public HashMap<Integer, String> getConfigs() {
		return configs;
	}

	public static void main(String[] args)
	{
		Server.getInstance();
		Server.getInstance().init();
	}
}